﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Web;

namespace CreativeMinds.StopForumSpam.HTTP {

	public abstract class HTTPClient {

		/// <summary>
		/// Constructor of a HTTPClient.
		/// </summary>
		protected HTTPClient() {
			this.Timeout = 5;
		}

		/// <summary>
		/// Timeout of the requests.
		/// </summary>
		public Int32 Timeout { get; set; }

		/// <summary>
		/// Send a GET request to the given url.
		/// </summary>
		/// <param name="url">Destination of the GET request</param>
		/// <returns>The data returned in the response to the request</returns>
		protected String Get(Uri url) {
			return this.Get(url, null);
		}

		/// <summary>
		/// Send a GET request to the given url with the given paramters.
		/// </summary>
		/// <param name="url">Destination of the GET request</param>
		/// <param name="parameters">The parameters of the request</param>
		/// <returns>The data returned in the response to the request</returns>
		protected String Get(Uri url, Dictionary<String, String> parameters) {
			return this.Request(HTTPMethod.GET, url, parameters);
		}

		/// <summary>
		/// Send a POST request to the given Url.
		/// </summary>
		/// <param name="url">Destination of the POST request</param>
		/// <returns>The data returned in the response to the request</returns>
		protected String Post(Uri url) {
			return this.Post(url, null);
		}

		/// <summary>
		/// Send a POST request the given parameters to the given Url.
		/// </summary>
		/// <param name="url">Destination of the POST request</param>
		/// <param name="parameters">The parameters of the request</param>
		/// <returns>The data returned in the response to the request</returns>
		protected String Post(Uri url, Dictionary<String, String> parameters) {
			return this.Request(HTTPMethod.POST, url, parameters);
		}

		/// <summary>
		/// A HTTP request of the given type, to the given Url and with the given parameters are created.
		/// </summary>
		/// <param name="method">Request method</param>
		/// <param name="url">The destinatio Url of the request</param>
		/// <param name="parameters">The parameters for the request</param>
		/// <returns>The data returned in the response to the request</returns>
		protected String Request(HTTPMethod method, Uri url, Dictionary<String, String> parameters) {
			UTF8Encoding encoding = new UTF8Encoding();
			String data = String.Empty;
			if (parameters != null) {
				data = BuildParameterString(parameters);
			}

			if (method == HTTPMethod.GET) {
				url = new Uri(url.ToString() + "?" + data);
			}

			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
			request.Method = method.ToString();
			request.Timeout = this.Timeout * 1000;
			request.UserAgent = String.Format("Stop Forum Spam .Net v{0}", this.GetType().Assembly.GetName().Version);
			if (method == HTTPMethod.POST) {
				request.ContentType = "application/x-www-form-urlencoded";

				Byte[] byteData = encoding.GetBytes(data);
				request.ContentLength = byteData.Length;
				Stream stream = request.GetRequestStream();
				stream.Write(byteData, 0, byteData.Length);
				stream.Close();
			}

			WebResponse response = (WebResponse)request.GetResponse();
			Stream readStream = null;
			readStream = response.GetResponseStream();
			StreamReader responseStream = new StreamReader(readStream, Encoding.UTF8);

			String output = responseStream.ReadToEnd();

			response.Close();
			responseStream.Close();

			return output;
		}

		private String BuildParameterString(Dictionary<String, String> parameters) {
			String output = String.Empty;
			foreach (KeyValuePair<String, String> pair in parameters) {
			        output += BuildSet(pair.Key, (String)pair.Value);
			}
			//foreach (KeyValuePair<String, Object> pair in parameters) {
			//    if (pair.Value == null) {
			//        output += BuildSet(pair.Key, "");
			//    }
			//    else if (pair.Value is String) {
			//        output += BuildSet(pair.Key, (String)pair.Value);
			//    }
			//    else if (pair.Value is Int32) {
			//        output += BuildSet(pair.Key, ((Int32)pair.Value).ToString());
			//    }
			//    else if (pair.Value is Int32) {
			//        output += BuildSet(pair.Key, ((Int32)pair.Value).ToString());
			//    }
			//    else if (pair.Value is Enum) {
			//        output += BuildSet(pair.Key, ((Enum)pair.Value).ToString());
			//    }
			//    else if (pair.Value.GetType().IsGenericType && pair.Value is List<String>) {
			//        foreach (String value in (List<String>)pair.Value) {
			//            output += BuildSet(pair.Key, value);
			//        }
			//    }
			//}

			return (String.IsNullOrEmpty(output) ? "" : output.Substring(0, output.Length - 1));
		}

		private String BuildSet(String key, String value) {
			return String.Format("{0}={1}&", key, HttpUtility.UrlEncode(value));
		}
	}
}